import de.looksgood.ani.*;
import de.looksgood.ani.easing.*;

import processing.opengl.*;

import codeanticode.glgraphics.*;

import de.fhpotsdam.unfolding.mapdisplay.*;
import de.fhpotsdam.unfolding.utils.*;
import de.fhpotsdam.unfolding.marker.*;
import de.fhpotsdam.unfolding.tiles.*;
import de.fhpotsdam.unfolding.interactions.*;
import de.fhpotsdam.unfolding.*;
import de.fhpotsdam.unfolding.core.*;
import de.fhpotsdam.unfolding.geo.*;
import de.fhpotsdam.unfolding.events.*;
import de.fhpotsdam.utils.*;
import de.fhpotsdam.unfolding.providers.*;
static int numberOfLines = 25;
Vehicle vehicle[];
float[][] screenPositions;

float rotation = 1;

boolean pause;
Route routes[];
color colors[] = {
#00A1DE, #00A1DE, #C60C30, #C60C30, 
#009B3A, #009B3A, #009B3A, #009B3A, 
#62361B, #62361B, #62361B, #522398, 
#522398, #522398, #62361B, #F9E300, 
#F9461C, #E27EA6, #522398, #62361B, 
#00A1DE, #00A1DE, #00A1DE, #62361B, 
#00A1DE, #522398};

de.fhpotsdam.unfolding.Map map;
de.fhpotsdam.unfolding.Map map1;
de.fhpotsdam.unfolding.Map map2;
de.fhpotsdam.unfolding.Map map3;

float[][] cood;
float[] home;

Location tmpLocation = new Location(0, 0);

Route parseData(String[] lines)
{
    cood = new float[lines.length][2];
    String []splt = lines[lines.length/2].split(",");
    String routeid = new String(splt[5]);
    String routename = new String(splt[5]);
    String col = new String(splt[6]);
    home[0] = Float.parseFloat(splt[1]);
    home[1] = Float.parseFloat(splt[2]);
    map.zoomAndPanTo(new Location(home[0], home[1]), 11);
    
    for (int i=0; i<lines.length; ++i) {
        if (trim(lines[i]).length() == 0) continue;
        String[] pieces = lines[i].split(",");
        cood[i][0] = (float)Float.parseFloat(pieces[1]);
        cood[i][1] = (float)Float.parseFloat(pieces[2]);
    }
    Route route = new Route(map, routeid, routename, cood, col);
    route.coordinates = route.simplifyCoordinates(route.coordinates);
    route.convertCoordinatesToPositions(route.coordinates);
    
    /*
    for (int i=0; i<route.screenPositions.length; ++i) {
        println(route.screenPositions[i][0] + " " + route.screenPositions[i][1]);
    }
    println(route.routeName + " has " + route.screenPositions.length);
    */
    return route;
}

void setup()
{
    size(1200, 800, GLConstants.GLGRAPHICS);
    home = new float[2];
    map = new de.fhpotsdam.unfolding.Map(this, 0, 0, 800, 800,
          new OpenStreetMap.CloudmadeProvider("d3e0942376a3438b8d5fce7378307b58", 46657));
    MapUtils.createDefaultEventDispatcher(this, map);
    map1 = new de.fhpotsdam.unfolding.Map(this, 800, 0, 400, 400,
           new OpenStreetMap.CloudmadeProvider("d3e0942376a3438b8d5fce7378307b58", 46657));
    MapUtils.createDefaultEventDispatcher(this, map1);
    map2 = new de.fhpotsdam.unfolding.Map(this, 800, 400, 400, 400,
           new OpenStreetMap.CloudmadeProvider("d3e0942376a3438b8d5fce7378307b58", 46657));
    MapUtils.createDefaultEventDispatcher(this, map2);
    //map3 = new de.fhpotsdam.unfolding.Map(this, 600, 400, 200, 200);
    String[] lines;
    vehicle = new Vehicle[numberOfLines];
    routes = new Route[numberOfLines];
   
    for (int i=0; i<numberOfLines; ++i) {
        lines = loadStrings("out" + i + ".txt");
        routes[i] = parseData(lines);
        vehicle[i] = new Vehicle(routes[i]);
    }
    
    Location loc = new Location(home[0], home[1]);
    map1.zoomAndPanTo(loc, 13);
    loc = new Location(home[0], home[1]);
    map2.zoomAndPanTo(loc, 2);
    pause = false;
    smooth();
    
    /*Ani.init(this);
    Ani diameterAni = new Ani(this, 1.5, 0.5, "diameter", 50, 50, Ani.EXPO_IN_OUT, "onEnd:randomize");
    diameterAni.setPlayMode(Ani.YOYO);
    diameterAni.repeat();
    //colorMode(HSB, 100);
    //frameRate(30);
    //strokeWeight(4);*/
    
    textAlign(CENTER);
    
}

void mousePressed()
{
    if (map.isHit(mouseX, mouseY)) {
        pause = true;
        for (int i=0; i<numberOfLines; ++i) {
            vehicle[i].freeze();
        }
    }
}

void keyPressed()
{
    switch (keyCode) {
        case 44:
             map.innerRotate(rotation);
            break;
        case 46:
             map.innerRotate(-rotation);
            break;
        case 32:
            map.zoomAndPanTo(new Location(home[0], home[1]), 11);
            break;
    }
}

void mouseReleased()
{
    if (pause) {
        pause = false;
    }
}

void draw()
{
    background(255);
    map.draw();
   //map3.draw();
    
    for (int i=0; i<numberOfLines; ++i) {

        routes[i].setMap(map);
        stroke(colors[i], 90);
        
        routes[i].convertCoordinatesToPositions(routes[i].coordinates);
        screenPositions = routes[i].screenPositions;
        
        strokeWeight(3);
        for (int j=1; j<screenPositions.length; ++j) {
            ellipse(screenPositions[j][0], screenPositions[j][1], 4, 4);
            line(screenPositions[j-1][0], screenPositions[j-1][1],
             screenPositions[j][0], screenPositions[j][1]);
        }
    }
    noStroke();
    for (int i=0; i<numberOfLines; ++i) {
        fill(colors[i]);
        if (mousePressed && pause) {
            vehicle[i].recalculateCurPosition();
        } else {
            vehicle[i].move();
        }
        ellipse(vehicle[i].curPosition[0], vehicle[i].curPosition[1], 10, 10);
    }
    
    map2.draw();
    tmpLocation.setLat(home[0]);
    tmpLocation.setLon(home[1]);
    float[] xy = map2.getScreenPositionFromLocation(tmpLocation);
    
    fill(232, 122, 312, 80);
    
    ellipse(xy[0], xy[1], 20, 20);
 
    map1.draw();
    /*
    for (int i=0; i<numberOfLines; ++i) {
        routes[i].setMap(map1);
        stroke(colors[i], 90);
        routes[i].convertCoordinatesToPositions(routes[i].coordinates);
        screenPositions = routes[i].screenPositions;
        
        for (int j=1; j<screenPositions.length; ++j) {
            ellipse(screenPositions[j][0], screenPositions[j][1], 4, 4);
            line(screenPositions[j-1][0], screenPositions[j-1][1],
             screenPositions[j][0], screenPositions[j][1]);
        }
    }
    */
   
}
